class User < ActiveRecord::Base

  # Associations
  has_one :info, :class_name => "InformacaoUsuario"
  accepts_nested_attributes_for :info
  delegate :matricula_siape, :telefone, :funcao, :to => :info, :allow_nil => true

  has_many :pleitos, :readonly => true

  attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :cpf, :matricula, :info_attributes

  # Authentication
  devise :registerable, :database_authenticatable, :recoverable, :rememberable,
         :trackable, :validatable, :lockable, :timeoutable

  # Authorization
  ROLES = %w(admin analista representante representante_sudam conferente distribuidor certificador recomendador deliberador).freeze

  # Order
  default_scope :order => :name

  named_scope :by_role, lambda { |role|
    { :conditions => ['roles_mask & ? != 0', User.mask(role)] }
  }

  def roles=(*roles)
    self[:roles_mask] = User.mask(roles)
  end

  def roles
    ROLES.reject{ |role| !has_role?(role) }
  end

  def role_symbols
    roles.map(&:to_sym)
  end

  def roles_string
    roles.join(";")
  end

  def has_role?(role)
    !((roles_mask || 0) & User.mask_for(role.to_s)).zero?
  end

  def self.mask(*roles)
    (roles.flatten.map!(&:to_s) & ROLES).map{ |role| mask_for(role) }.sum
  end

  def self.mask_for(role)
    2**ROLES.index(role)
  end

  before_create :setup_roles

  def setup_roles
    self.roles = :representante if roles.empty?
  end

  # Validations
  validates_cpf_of          :cpf
  validates_presence_of     :cpf
  validates_uniqueness_of   :cpf

  validates_presence_of     :name
  validates_length_of       :name, :maximum => 100, :allow_nil => true

  # Callbacks
  # FIXME before_delete checar se eh o ultimo admin

  # Helpers
  def pleitos_em_analise
    Pleito.analisando.all(:joins => :analise, :order => "codigo", :conditions => ["analista_1_id = ? OR analista_2_id = ?", self.id, self.id])
  end

  def cpf=(value)
    write_attribute :cpf, value.try(:gsub, /\D/, '')
  end

  # Devise hack
  def self.find_for_authentication(conditions)
    conditions[:cpf] = conditions[:cpf].try(:gsub, /\D/, '')
    super
  end
  
  def recuperar_pleitos
    if(roles_mask == 1)
      lista = Pleito.all
    else
      lista = pleitos
    end
    return lista
  end
end
